﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kokomo.Environment.Services
{
	/// <summary>
	/// Provides functionality to manage documents.
	/// </summary>
	/// <remarks>
	/// The environment provides an implementation of this interface,
	/// and can be retrieved via <see cref="EnvironmentServices"/>.
	/// </remarks>
	public interface IDocumentManager
	{
		/// <summary>
		/// Gets a list of <see cref="DocumentViewModel"/>s currently open in the environment.
		/// </summary>
		IEnumerable<DocumentViewModel> DocumentViewModels { get; }
		/// <summary>
		/// Finds an open instance of a <see cref="DocumentViewModel"/> for a given path.
		/// </summary>
		/// <param name="path">The path of the document.</param>
		/// <returns>The instance of <see cref="DocumentViewModel"/> corresponding to the <paramref name="path"/>,
		/// if it is open; otherwise, <c>null</c>.</returns>
		/// <exception cref="ArgumentNullException"><paramref name="path"/> is <c>null</c>.</exception>
		DocumentViewModel FindOpenDocumentForPath(string path);
		/// <summary>
		/// Opens a document from a file.
		/// </summary>
		/// <param name="fileName">File name of the document to open.</param>
		/// <returns>An <see cref="DocumentViewModel"/> representing the document loaded from <paramref name="fileName"/>, or <c>null</c>.</returns>
		/// <exception cref="ArgumentNullException"><paramref name="fileName"/> is <c>null</c>.</exception>
		/// <remarks>
		/// The implementation should check whether the document is already open,
		/// and if it is, return the existing instance.
		/// This method may return <c>null</c> if the operation is canceled,
		/// or completed through some other means.
		/// <para>
		/// The default implementation provided by the environment delegates
		/// the operation to the <see cref="DocumentEditor"/> associated with the file type.
		/// If successful, it associates the <see cref="DocumentViewModel"/> returned
		/// by the editor with <paramref name="fileName"/> and displays it.
		/// </para>
		/// </remarks>
		DocumentViewModel OpenDocumentFromFile(string fileName);
		/// <summary>
		/// Adds a document to the list to be displayed by the application.
		/// </summary>
		/// <param name="documentViewModel">The <see cref="DocumentViewModel"/> to display.</param>
		/// <exception cref="ArgumentNullException"><paramref name="documentViewModel"/> is <c>null</c>.</exception>
		void ShowDocument(DocumentViewModel documentViewModel);

		/// <summary>
		/// Creates an <see cref="ErrorDocumentViewModel"/>.
		/// </summary>
		/// <param name="mainCaption">The main error caption</param>
		/// <param name="detail">The error detail</param>
		/// <param name="exception">The exception describing the error</param>
		/// <param name="documentFileName">The file name of the document causing the error.</param>
		/// <returns>A new <see cref="ErrorDocumentViewModel"/>.</returns>
		/// <remarks>
		/// If <paramref name="documentFileName"/> is specified, the error document
		/// contains a link to allow the user to retry opening the document.
		/// </remarks>
		/// <seealso cref="ErrorDocumentViewModel"/>
		ErrorDocumentViewModel CreateErrorDocumentViewModel(
			UiString mainCaption,
			UiString detail,
			Exception exception = null,
			string documentFileName = null
			);
		/// <summary>
		/// Creates an <see cref="ErrorDocumentViewModel"/> and displays it.
		/// </summary>
		/// <param name="mainCaption">The main error caption</param>
		/// <param name="detail">The error detail</param>
		/// <param name="exception">The exception describing the error</param>
		/// <param name="documentFileName">The file name of the document causing the error.</param>
		/// <returns>A new <see cref="ErrorDocumentViewModel"/>.</returns>
		/// <remarks>
		/// If <paramref name="documentFileName"/> is specified, the error document
		/// contains a link to allow the user to retry opening the document.
		/// </remarks>
		/// <seealso cref="ErrorDocumentViewModel"/>
		ErrorDocumentViewModel CreateAndShowErrorDocumentViewModel(
			UiString mainCaption,
			UiString detail,
			Exception exception = null,
			string documentFileName = null
			);

		/// <summary>
		/// Gets or sets the <see cref="DocumentViewModel"/> the user is interacting with.
		/// </summary>
		DocumentViewModel ActiveDocumentViewModel { get; set; }
		/// <summary>
		/// Raised when a different <see cref="DocumentViewModel"/> is activated.
		/// </summary>
		event EventHandler ActiveDocumentChanged;
	}
}
